package com.example.jobback.service.manager.impl;

import com.alibaba.fastjson.JSON;
import com.example.jobback.common.enums.VerifyCompanyRegisterStatus;
import com.example.jobback.config.AuthConfig;
import com.example.jobback.dto.RecruiterRegisterDto;
import com.example.jobback.mapper.VerifyCompanyRecordMapper;
import com.example.jobback.po.Manager;
import com.example.jobback.po.User;
import com.example.jobback.req.common.page.PageReq;
import com.example.jobback.resp.manager.company.page.MCrossGetPageCompanyListResp;
import com.example.jobback.resp.manager.company.page.MCrossGetPageCompanyResp;
import com.example.jobback.resp.manager.company.register.RecruiterRegisterResp;
import com.example.jobback.resp.manager.employee.page.seeker.MCrossGetPageSeekerResp;
import com.example.jobback.resp.manager.employee.page.seeker.MCrossGetPageSeekersResp;
import com.example.jobback.resp.recruiter.company.page.RCrossGetPageCompanyListResp;
import com.example.jobback.resp.recruiter.company.page.RCrossGetPageCompanyResp;
import com.example.jobback.resp.recruiter.position.search.RCrossSearchJobOrCompanyResp;
import com.example.jobback.resp.seeker.common.page.SCrossGetPageSeekerResp;
import com.example.jobback.resp.seeker.common.page.SCrossGetPageSeekersResp;
import com.example.jobback.result.Result;
import com.example.jobback.service.common.UserCommonService;
import com.example.jobback.service.manager.ManagerCompanyService;
import com.example.jobback.util.CACHEUtil;
import com.example.jobback.util.CrossServiceInvoker;
import com.example.jobback.util.TLUtil;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.web.client.RestTemplate;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.TimeUnit;

import static com.example.jobback.util.RedisConstants.*;
import static com.example.jobback.util.RedisConstants.MANAGER_TTL;

/**
 * @ClassName: ManagerCompanyServiceImpl
 * @Description:管理员-公司管理服务实现类
 * @Author: lhb
 * @Date: 2025/6/21
 */
@Service
public class ManagerCompanyServiceImpl implements ManagerCompanyService {

    private final UserCommonService userCommonService;

    private final CACHEUtil cacheUtil;

    private final VerifyCompanyRecordMapper verifyCompanyRecordMapper;

    private final AuthConfig authConfig;

    private final RestTemplate restTemplate;



    @Value("${cross_service_baseurl}")
    private String crossServiceBaseUrl;

    public ManagerCompanyServiceImpl(UserCommonService userCommonService, CACHEUtil cacheUtil, AuthConfig authConfig, VerifyCompanyRecordMapper verifyCompanyRecordMapper, RestTemplate restTemplate) {
        this.userCommonService = userCommonService;
        this.cacheUtil = cacheUtil;
        this.authConfig = authConfig;
        this.verifyCompanyRecordMapper = verifyCompanyRecordMapper;
        this.restTemplate = restTemplate;
    }

    /**
     * @Description: 审核公司注册
     * @param oldPhoneAes 待处理加密手机号
     * @return Result<Object>
     * @Author lhb
     * @CreateTime 2025/6/21 15:24
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Object> verifyUserCompanyRegister(String oldPhoneAes) {
        //解决+号被转出空格的bug，+号在http传输会被替换成空格
        String phoneAes = oldPhoneAes.replace(" ", "+");
        Manager manager= TLUtil.get(TLUtil.M);
        Long userId=manager.getUserId();
        String value = cacheUtil.get(VERIFY_RECRUITER_REGISTER_USER_KEY + phoneAes);
        if(value==null) {
            //可能有数据未一致问题。删除集合元素
            cacheUtil.removeMember(VERIFY_RECRUITER_REGISTER_USERS_KEY,phoneAes);
            throw new RuntimeException("审核失败，内容已失效");
        }
        RecruiterRegisterDto recruiterRegisterDto = JSON.parseObject(value, RecruiterRegisterDto.class);
        User user = userCommonService.getUserByPhoneAes(phoneAes);
        //注册用户
        if(user==null) {
            user = userCommonService.registerUser(phoneAes);
            if(user ==null) throw new RuntimeException("注册失败");
            //传入姓名
            user.setName(recruiterRegisterDto.getUserName());
            userCommonService.editBasicMessage(user);
        }
        else {
            //替换提交时的用户名
            String newUserName = recruiterRegisterDto.getUserName();
            if(newUserName!=null && !newUserName.isEmpty()){
                user.setName(recruiterRegisterDto.getUserName());
                userCommonService.editBasicMessage(user);
            }
        }
        //注册公司和招聘者
        recruiterRegisterDto.setUserId(user.getUserId());
        //删除审核公司表记录
        if(verifyCompanyRecordMapper.deleteRecordByPhoneAes(phoneAes)==0) throw new RuntimeException("注册失败");
        //提交事务后，再发起跨服务调用
        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
            @Override
            public void afterCommit() {
                // 异步调用 registerCompany
                try {
                    if(!registerRecruiterCompany(recruiterRegisterDto,userId)) throw new RuntimeException("注册失败");
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        });
        //删除sortSet集合的元素，和对应的元素内容
        cacheUtil.removeMember(VERIFY_RECRUITER_REGISTER_USERS_KEY,phoneAes);
        cacheUtil.deleteKeySafely(VERIFY_RECRUITER_REGISTER_USER_KEY + phoneAes);
        //延时登录态
        String token=userCommonService.updateRedisUserToken(manager.getUserId(),MANAGER_KEY,authConfig.getJwtManagerSecret(),MANAGER_TTL, TimeUnit.DAYS);
        if(token==null) throw new RuntimeException("token生成失败");
        return Result.success(token);
    }

    /**
     * @Description: 获取待审核注册公司的列表
     * @return Result<Set<RecruiterRegisterResp>>
     * @Author lhb
     * @CreateTime 2025/6/21 15:28
     */
    @Override
    public Result<Set<RecruiterRegisterResp>> getRecruiterCompanyRegisterLists() {
        Set<String> phoneAesByRank = cacheUtil.getMembersByRank(VERIFY_RECRUITER_REGISTER_USERS_KEY, 0, -1);
        Set<RecruiterRegisterResp> recruiterRegisterRespSet=new HashSet<>();
        for(String phoneAes:phoneAesByRank){
            String value = cacheUtil.get(VERIFY_RECRUITER_REGISTER_USER_KEY + phoneAes);
            if(value==null) {
                //可能有数据未一致问题。删除集合元素
                cacheUtil.removeMember(VERIFY_RECRUITER_REGISTER_USERS_KEY,phoneAes);
                continue;
            }
            RecruiterRegisterDto recruiterRegisterDto = JSON.parseObject(value, RecruiterRegisterDto.class);
            RecruiterRegisterResp recruiterRegisterResp=new RecruiterRegisterResp();
            BeanUtils.copyProperties(recruiterRegisterDto, recruiterRegisterResp);
            recruiterRegisterRespSet.add(recruiterRegisterResp);
        }
        return Result.success(recruiterRegisterRespSet);
    }

    /**
     * @Description: 审核公司注册不通过
     * @param oldPhoneAes 待处理加密手机号
     * @param message
     * @return Result<Object>
     * @Author lhb
     * @CreateTime 2025/6/21 15:29
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Object> verifyUserCompanyRegisterFailed(String oldPhoneAes, String message) {
        //解决+号被转出空格的bug，+号在http传输会被替换成空格
        String phoneAes = oldPhoneAes.replace(" ", "+");
        Manager manager=TLUtil.get(TLUtil.M);
        if(verifyCompanyRecordMapper.registerFailed(phoneAes, VerifyCompanyRegisterStatus.VERIFY_FAILED,message)==0){
            throw new RuntimeException("操作失败");
        }
        //删除sortSet集合的元素，和对应的元素内容
        cacheUtil.removeMember(VERIFY_RECRUITER_REGISTER_USERS_KEY,phoneAes);
        cacheUtil.deleteKeySafely(VERIFY_RECRUITER_REGISTER_USER_KEY + phoneAes);
        //延时登录态
        String token=userCommonService.updateRedisUserToken(manager.getUserId(),MANAGER_KEY,authConfig.getJwtManagerSecret(),MANAGER_TTL,TimeUnit.DAYS);
        return Result.success(token);
    }

    /**
     * @Description: 跨服务调用，分页查询公司列表
     * @param page
     * @param size
     * @param content 
     * @return Result<MCrossGetPageCompistResp>
     * @Author lhb
     * @CreateTime 2025/7/4 12:04
     */
    @Override
    public Result<MCrossGetPageCompanyListResp> getCompanyList(int page, int size, String content) {
        Manager manager=TLUtil.get(TLUtil.M);
        Long userId=manager.getUserId();
        //跨服务调用
        PageReq pageReq=new PageReq();
        pageReq.setContent(content);
        pageReq.setPage(page);
        pageReq.setSize(size);
        String url = crossServiceBaseUrl + "/recruiter/company/getCompanyList";
        // 手动创建 CrossServiceInvoker 实例
        CrossServiceInvoker invoker =
                new CrossServiceInvoker(authConfig, restTemplate);
        Result<Object> result = null;
        try {
            result = invoker.invokeAndHandle(
                    url,
                    HttpMethod.POST,
                    pageReq,
                    Object.class,
                    userId,
                    null
            );
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        if(!result.getCode().equals(HttpServletResponse.SC_CREATED)) {
            throw new IllegalArgumentException("VALIDATION_ERROR：查询失败");
        }
        RCrossGetPageCompanyListResp rCrossGetPageCompanyListResp =
                JSON.parseObject(JSON.toJSONString(result.getData()),
                RCrossGetPageCompanyListResp.class);
        //初始化响应体
        MCrossGetPageCompanyListResp resp=new MCrossGetPageCompanyListResp();
        resp.setRespList(new ArrayList<>());
        //因为BeanUtils的权限，使用循环构造
        BeanUtils.copyProperties(rCrossGetPageCompanyListResp, resp);
        for (RCrossGetPageCompanyResp rCrossGetPageCompanyResp : rCrossGetPageCompanyListResp.getRespList()) {
            MCrossGetPageCompanyResp mCrossGetPageCompanyResp=new MCrossGetPageCompanyResp();
            BeanUtils.copyProperties(rCrossGetPageCompanyResp, mCrossGetPageCompanyResp);
            resp.getRespList().add(mCrossGetPageCompanyResp);
        }
        return Result.success(resp);
    }


    /**
     * @Description: 跨服务调用recruiter，注册公司
     * @param recruiterRegisterDto
     * @param userId
     * @return boolean
     * @Author lhb
     * @CreateTime 2025/6/21 15:26
     */
    public boolean registerRecruiterCompany(RecruiterRegisterDto recruiterRegisterDto,Long userId){
        String url = crossServiceBaseUrl + "/recruiter/auth/registerCompany";
        // 手动创建 CrossServiceInvoker 实例
        CrossServiceInvoker invoker =
                new CrossServiceInvoker(authConfig, restTemplate);
        Result<Object> result = null;
        try {
            result = invoker.invokeAndHandle(
                    url,
                    HttpMethod.POST,
                    recruiterRegisterDto,
                    Object.class,
                    userId,
                    null
            );
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return result.getCode().equals(HttpServletResponse.SC_CREATED);
    }
}
